<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>My first three.js app</title>
    <style>
        html, body {
            margin: 0;
            height: 100%;
        }
        #c {
            width: 100%;
            height: 100%;
            display: block;
        }
    </style>

    <script src="./three.js-r148/build/three.js"></script>
</head>
<body>
<canvas id="c"></canvas>


<script>
    function main() {
        const canvas = document.querySelector('#c');

        // 渲染器
        const renderer = new THREE.WebGLRenderer({antialias: true, canvas});

        // 创建摄像机
        const fov = 75;
        const aspect = 2;  // 相机默认值
        const near = 0.1;
        const far = 5;
        const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

        camera.position.z = 2;

        // 创建场景
        const scene = new THREE.Scene();

        {
            // 加入平行光
            const color = 0xFFFFFF;
            const intensity = 3;
            const light = new THREE.DirectionalLight(color, intensity);
            light.position.set(-1, 2, 4);
            scene.add(light);
        }

        // 创建一个几何体
        const boxWidth = 1;
        const boxHeight = 1;
        const boxDepth = 1;
        const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

        // 创建材质
        // const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
        const material = new THREE.MeshPhongMaterial({color: 0x44aa88});

        // 创建一个网格
        // const cube = new THREE.Mesh(geometry, material);

        // 创建多个
        const cubes = [
            makeInstance(geometry, 0x44aa88,  0),
            makeInstance(geometry, 0x8844aa, -2),
            makeInstance(geometry, 0xaa8844,  2),
        ];

        // 添加网格
        // scene.add(cube);

        // 将场景和摄像机加入渲染器
        renderer.render(scene, camera);

        // 到这里很难看出来这是一个三维的立方体，因为我们直视Z轴的负方向并且立方体和坐标轴是对齐的，所以我们只能看到一个面。
        // 我们来让立方体旋转起来，以便更好的在三维环境中显示。为了让它动起来我们需要用到一个渲染循环函数
        // requestAnimationFrame.

        function resizeRendererToDisplaySize(renderer) {
            const canvas = renderer.domElement;
            const width = canvas.clientWidth;
            const height = canvas.clientHeight;
            const needResize = canvas.width !== width || canvas.height !== height;
            if (needResize) {
                console.log('canvas宽高和渲染器宽高不一致')
                renderer.setSize(width, height, false);
            }
            return needResize;
        }


        function render(time) {
            time *= 0.001;  // 将时间单位变为秒

            cubes.forEach((cube, ndx) => {
                const speed = 1 + ndx * .1;
                const rot = time * speed;
                cube.rotation.x = rot;
                cube.rotation.y = rot;
            });

            // 让正方形保持不变形
            // const canvas = renderer.domElement;
            // camera.aspect = canvas.clientWidth / canvas.clientHeight;
            // camera.updateProjectionMatrix();

            // 先检查canvas是否真的需要调整大小
            if (resizeRendererToDisplaySize(renderer)) {
                const canvas = renderer.domElement;
                camera.aspect = canvas.clientWidth / canvas.clientHeight;
                camera.updateProjectionMatrix();
            }

            renderer.render(scene, camera);

            requestAnimationFrame(render);
        }
        requestAnimationFrame(render);

        function makeInstance(geometry, color, x) {
            const material = new THREE.MeshPhongMaterial({color});

            const cube = new THREE.Mesh(geometry, material);
            scene.add(cube);

            cube.position.x = x;

            return cube;
        }
    }
    main()
</script>
</body>
</html>
